#ifndef __CHARACTER_H__
#define __CHARACTER_H__

#include "cocos2d.h"
#include "Supporting/Enums/EnumCharacterState.h"
#include "Supporting/Singleton.h"

using namespace cocos2d;

class GameMap;
class CharacterAI;
class GameMap;

class Character : public CCSprite, public Singleton<Character>
{
private:
	//============= CHARACTER AI variables and functions =============
	CharacterAI*			_pCharBaseAI;		// AI class to decide on actions

	//============= ANIMATION variables and functions =============
	static const float 		RECT_BUFFER_RADIUS = 20; // radius pixels
	CCAnimate* 				_pRunningAnimate;	// Stores the running animation
	CCAnimate*				_pInjuredAnimate;
	char*					_filename;

	static CCSpriteFrame* 	createSpriteFrame(char* filename);
	void					loadSprite(char* filename);
	void					playRunningAnimation();
	void					playInjuredAnimation();
	void 					initCharacterSprites(char* filename, GameMap* pMap);

	//============= CHARACTER STATE functions =============
	static const int 		BASE_OBSTACLE_HIT_CHANCE = 5;	// %
	static const float 		STOP_SPEED_MULTIPLIER = 2; // divide the speed multiplier by this
	static const int		STOP_DURATION = 4; // in seconds
	float					_stopTimer;
	CC_SYNTHESIZE(int, _obstacleHitChance, ObstacleHitChance);
	CC_SYNTHESIZE(EnumCharacterState, _charState, CharState);

	void			 		runStraight(float timeDiff);
	void			 		runUp(float timeDiff);
	void		  	 		runDown(float timeDiff);
	void		 	 		hitObstacle(float timeDiff);
	void			 		stop(float timeDiff);
	void			 		dead(float timeDiff);

	//============= MOVEMENT functions =============
	static const int   		BASE_SPEED_X = 140; // x and y speed
	static const int   		BASE_SPEED_Y = 50; // x and y speed
	static const float 		BASE_SPEED_MULTIPLIER = 1.0;
	int				   		_maxMoveDistance;
	float			   		_amountMoved;
	CC_SYNTHESIZE(int, _speedX, SpeedX);
	CC_SYNTHESIZE(int, _speedY, SpeedY);
	CC_SYNTHESIZE(float, _speedMultiplier, SpeedMultiplier);
	CC_SYNTHESIZE(float, _directorSpeedMultiplier, DirectorSpeedMultiplier);

	float			   		destinationCheck(float moveAmount);

	//============= HEALTH variables and functions =============
	static const int 		BASE_HEALTH = 3;
	int				 		_health;

	//============= IMMUNITY variables and functions =============
	static const int 		IMMUNITY_DURATION = 2; //in seconds
	bool			 		_isImmune;
	float			 		_immunityTimer;	// Count down to 0 before being vulnerable

	void			 		updateImmunity(float timeDiff);

public:
	//============= TOUCH variables and functions =============
	CC_SYNTHESIZE(CCPoint, _nextPosition, NextPosition);
	CC_SYNTHESIZE(CCPoint, _vector, Vector);
	CC_SYNTHESIZE(CCTouch *, _touch, Touch);

	//===== CONSTRUCTOR =====
	Character(); //do not use
	void init(char* filename, GameMap* pMap);

	//===== DESTRUCTOR =====
	~Character(void);

	//===== FUNCTIONS =====
	void					update(float timeDiff);			// Update the character's action
	void					reduceHealth(int health);		// Reduce character's health, if < 0, character dies

	//===== GETTERS/SETTERS =====
	CCRect 					getRect(); //used for collision detection
	float 					getXSpeed(float timeDiff);
	float					getYSpeed(float timeDiff);
	int						getHealth()	{return _health;};
	bool 					isImmune() {return _isImmune;};
	bool					isDead() {return _charState == DEAD;};

	void 					updateDirectorObstacle(float obstacleHitChance);
	void 					updateDirectorSpeed(float speedMultiplier);
};

#endif // __CHARACTER_H__
